#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include "DetectCls.h"

#include <android/log.h>
#define LOG_TAG "UHYLab"
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#define QRBAR_SHIFTBITS    8
#define QRBAR_ROUND0(x)  (x>>QRBAR_SHIFTBITS)
#define QRBAR_ROUND1(x)  (ROUND0(x))+1

CUHYRecogCls::CUHYRecogCls()
{
	Front_FastDetectCls = NULL;
	SquarePos = NULL;

}

CUHYRecogCls::~CUHYRecogCls()
{

}

void CUHYRecogCls::DetectInit(char * path)
{

	Front_FastDetectCls=new CDetectModelCls(6);

	Front_FastDetectCls->LoadDetectModel();
    string s_path(path);
	SquarePos = new DETECT_DATA[1000000];

	//加载识别模型
	BaiXiBaoModel=ReadSVMModel((s_path +"/BaiXiBaoModel").c_str());
	YaXiaoSuanYanModel=ReadSVMModel((s_path +"/YaXiaoSuanYanModel").c_str());
	NiaoDanYuanModel=ReadSVMModel((s_path +"/NiaoDanYuanModel").c_str());
	DanBaiZhiModel=ReadSVMModel((s_path +"/DanBaiZhiModel").c_str());
	SuanJianDuModel=ReadSVMModel((s_path +"/SuanJianDuModel").c_str());
	QianXueModel=ReadSVMModel((s_path +"/QianXueModel").c_str());
	BiZhongModel=ReadSVMModel((s_path +"/BiZhongModel").c_str());
	TongTiModel=ReadSVMModel((s_path +"/TongTiModel").c_str());
	DanHongSuModel=ReadSVMModel((s_path +"/DanHongSuModel").c_str());
	PuTaoTangModel=ReadSVMModel((s_path +"/PuTaoTangModel").c_str());
	KangHuaiXueSuanModel=ReadSVMModel((s_path +"/KangHuaiXueSuanModel").c_str());

}

void BilinearResize_8u_1D_1R( unsigned char * pSrcImg, unsigned char * pDesImg, int srcWidth, int srcHeight, int desWidth, int desHeight )
{
	int i, j;
	int nRateW,nRateH;
	int y;
	unsigned short *coord_x, *coord_y;
	unsigned char *bi_coef_x, *bi_coef_y;
	unsigned char *sub_bi_coef_x, *sub_bi_coef_y;
	unsigned char *pImg_left_top, *pImg_left_down;
	unsigned char *pImg_right_top, *pImg_right_down;
	int float_value;
	const short std_1_value = (1<<QRBAR_SHIFTBITS);
	const short std_and_value = ((1<<QRBAR_SHIFTBITS)-1);
	int res_x0, res_x1;
	int res_xy;
	unsigned char *pSrc, *pSrc1;

	pImg_left_top = (unsigned char *)malloc(sizeof(char)*desWidth);
	pImg_left_down = (unsigned char *)malloc(sizeof(char)*desWidth);
	pImg_right_top = (unsigned char *)malloc(sizeof(char)*desWidth);
	pImg_right_down = (unsigned char *)malloc(sizeof(char)*desWidth);

	coord_x = (unsigned short *)malloc(sizeof(short)*desWidth);
	coord_y = (unsigned short *)malloc(sizeof(short)*desHeight);
	bi_coef_x = (unsigned char *)malloc(sizeof(char)*desWidth);
	bi_coef_y = (unsigned char *)malloc(sizeof(char)*desHeight);
	sub_bi_coef_x = (unsigned char *)malloc(sizeof(char)*desWidth);
	sub_bi_coef_y = (unsigned char *)malloc(sizeof(char)*desHeight);

	nRateW = (srcWidth<<QRBAR_SHIFTBITS) / desWidth;
	nRateH = (srcHeight<<QRBAR_SHIFTBITS) / desHeight;
	
	for(i = 0;i < desHeight; ++i)
	{
		float_value = i * nRateH;
		bi_coef_y[i] = float_value & std_and_value;
		if(!bi_coef_y[i])
			bi_coef_y[i] = 1;
		sub_bi_coef_y[i] = std_1_value - bi_coef_y[i];
		coord_y[i] = QRBAR_ROUND0(float_value);
		if(coord_y[i] > srcHeight - 2)
			coord_y[i] = srcHeight - 2;
	}
	
	for(i = 0;i < desWidth; ++i)
	{
		float_value = i * nRateW;
		bi_coef_x[i] = float_value & std_and_value;
		if(!bi_coef_x[i])
			bi_coef_x[i] = 1;
		sub_bi_coef_x[i] = std_1_value - bi_coef_x[i];
		coord_x[i] = QRBAR_ROUND0(float_value);
		if(coord_x[i] > srcWidth - 2)
			coord_x[i] = srcWidth - 2;
	}

	for (i = 0; i < desHeight; i++)
	{
		
		pSrc = pSrcImg + coord_y[i]*srcWidth;
		y = coord_y[i];
		for(j = 0;j < desWidth; j ++)
		{
			pSrc1 = pSrc;
			pSrc1 += coord_x[j];
			pImg_left_top[j] = *pSrc1;
			pImg_right_top[j] = *(pSrc1 + 1);
			pSrc1 += srcWidth;
			pImg_left_down[j] = *pSrc1;
			pImg_right_down[j] = *(pSrc1 + 1);
		}

#ifdef NEON_QRBAR_CODE_OPTIMIZATION
		unsigned char *img1, *img2, *img3, *img4;
		unsigned char *outimg;
		unsigned char *coef1, *coef2, *coef3, *coef4;
		unsigned char *coef_x1, *coef_x2;
		uint8x8_t value_y1, value_y2;

		value_y1 = vdup_n_u8(sub_bi_coef_y[i]);
		value_y2 = vdup_n_u8(bi_coef_y[i]);
		img1 = pImg_left_top;
		img2 = pImg_right_top;
		img3 = pImg_left_down;
		img4 = pImg_right_down;
		outimg = pDesImg + i*desWidth;
		coef_x1 = sub_bi_coef_x;
		coef_x2 = bi_coef_x;
		for(j = 0;j < desWidth; j += 8)
		{
			uint8x8_t v1, v2, v3, v4;
			uint8x8_t value_x1, value_x2;
			uint8x8_t bires_x0, bires_x1, bires_xy;
			uint16x8_t multi_value;

			v1 = vld1_u8(img1);
			v2 = vld1_u8(img2);
			v3 = vld1_u8(img3);
			v4 = vld1_u8(img4);

			value_x1 = vld1_u8(coef_x1);
			value_x2 = vld1_u8(coef_x2);
			multi_value = vmull_u8(v1, value_x1);
			multi_value = vmlal_u8(multi_value, v2, value_x2);
			bires_x0 = vshrn_n_u16(multi_value, QRBAR_SHIFTBITS);
			multi_value = vmull_u8(v3, value_x1);
			multi_value = vmlal_u8(multi_value, v4, value_x2);
			bires_x1 = vshrn_n_u16(multi_value, QRBAR_SHIFTBITS);
			multi_value = vmull_u8(bires_x0, value_y1);
			multi_value = vmlal_u8(multi_value, bires_x1, value_y2);
			bires_xy = vshrn_n_u16(multi_value, QRBAR_SHIFTBITS);
			vst1_u8(outimg, bires_xy);

			outimg += 8;
			img1 += 8;
			img2 += 8;
			img3 += 8;
			img4 += 8;
			coef_x1 += 8;
			coef_x2 += 8;
		}
		for(;j < desWidth;j ++)
		{
			res_x0 = (((*img1)*sub_bi_coef_x[j] + (*img2)*bi_coef_x[j])>>QRBAR_SHIFTBITS);
			res_x1 = (((*img3)*sub_bi_coef_x[j] + (*img4)*bi_coef_x[j])>>QRBAR_SHIFTBITS);
			res_xy = res_x0*sub_bi_coef_y[i] + res_x1*bi_coef_y[i];
			*outimg = (res_xy>>QRBAR_SHIFTBITS);
			outimg ++;
			img1 ++;
			img2 ++;
			img3 ++;
			img4 ++;
		}
#else
		for(j = 0;j < desWidth; j ++)
		{
			res_x0 = ((pImg_left_top[j]*sub_bi_coef_x[j] + pImg_right_top[j]*bi_coef_x[j])>>QRBAR_SHIFTBITS);
			res_x1 = ((pImg_left_down[j]*sub_bi_coef_x[j] + pImg_right_down[j]*bi_coef_x[j])>>QRBAR_SHIFTBITS);
			res_xy = res_x0*sub_bi_coef_y[i] + res_x1*bi_coef_y[i];
			pDesImg[i*desWidth + j] = (res_xy>>QRBAR_SHIFTBITS);
		}
#endif
	}

	free(coord_x);
	free(coord_y);
	free(bi_coef_x);
	free(bi_coef_y);
	free(sub_bi_coef_x);
	free(sub_bi_coef_y);
	free(pImg_left_top);
	free(pImg_left_down);
	free(pImg_right_top);
	free(pImg_right_down);
}


bool CUHYRecogCls::SquareDetect(unsigned char* imageData, int src_wd, int src_ht, DECTRECT* pRealRect,DECTRECT* pStdRect)
{
	
	int norm_max_wd_ht = 320;
	int new_wd, new_ht;
	float scale_rate = 1.0;
	if(src_wd > src_ht)
	{
		new_wd = norm_max_wd_ht;
		new_ht = norm_max_wd_ht*src_ht/src_wd;
		scale_rate = (float)src_wd/norm_max_wd_ht;
	}
	else
	{
		new_ht = norm_max_wd_ht;
		new_wd = norm_max_wd_ht*src_wd/src_ht;
		scale_rate = (float)src_ht/norm_max_wd_ht;
	}
	unsigned char *norm_image = new unsigned char[new_ht * new_wd];
	BilinearResize_8u_1D_1R( imageData, norm_image, src_wd, src_ht, new_wd, new_ht );

	unsigned char **image = f2b (new_ht, new_wd);
	bool detectFlag=false;

	for(int i = 0;i < new_ht; ++i)
	{
		for(int j=0; j<new_wd; j++)
		{
			image[i][j] =norm_image[i*new_wd + j];
		}
	}

	delete []norm_image;
	norm_image = NULL;
		

	int front_nSquare = Front_FastDetectCls->FastDetectAllSquarePosition_All(image, new_ht, new_wd, SquarePos);

	FreeArray_BYTE(image, new_ht, new_wd);
	front_nSquare = Front_FastDetectCls->CombineDetectedObjs(SquarePos, front_nSquare);
	if(front_nSquare<20)
	{
		return false;
	}

	SDPOINT* pMidPoint=new SDPOINT[front_nSquare];
	for(int ii = 0;ii < front_nSquare; ++ii)
	{

		pMidPoint[ii]=GetRectMidPoint(SquarePos[ii].square_rect);
	}						
		
	//通过两个点组合构造直线 2016.4.10 liuming
	float **lines;
	int linenum=(front_nSquare*(front_nSquare-1))/2;
	lines =new float *[linenum];

	DECTRECT realRect[LINE_SQUARE_NUM];
	SDPOINT realRectPoint[LINE_SQUARE_NUM];
	float distRealRect[LINE_SQUARE_NUM-1];

	DECTRECT stdRect[STD_SQUARE_NUM];

	int *pSquareIndex=new int[front_nSquare];
	int kk=0;
	for(int ii = 0;ii < front_nSquare; ++ii)
	{
		for(int jj=ii+1;jj<front_nSquare;jj++)
		{
			lines[kk]=new float[4];
			lines[kk][0]=pMidPoint[jj].x-pMidPoint[ii].x;
			lines[kk][1]=pMidPoint[jj].y-pMidPoint[ii].y;
			lines[kk][2]=pMidPoint[ii].x;
			lines[kk][3]=pMidPoint[ii].y;

			kk++;
		}
	}

	bool findflag=false;
	for(int ii=0;ii<linenum;ii++)
	{
		int kk=0;
		for(int jj=0;jj<front_nSquare;jj++)
		{
			float dist=getDot2LineDist(pMidPoint[jj],lines[ii]);
			if(dist<(SquarePos[jj].square_rect.bottom-SquarePos[jj].square_rect.top)*0.4)
			{
				pSquareIndex[kk]=jj;
				kk++;
					
			}
		}

		if(kk==LINE_SQUARE_NUM)
		{
			for(int nn=0;nn<LINE_SQUARE_NUM;nn++)
			{
				realRect[nn]=SquarePos[pSquareIndex[nn]].square_rect;
				realRectPoint[nn]=GetRectMidPoint(realRect[nn]);
			}

			sortRect(realRect,realRectPoint,11);

			for(int mm=0;mm<LINE_SQUARE_NUM-1;mm++)
			{
				distRealRect[mm]=sqrt((float)((realRectPoint[mm+1].y-realRectPoint[mm].y)
					*(realRectPoint[mm+1].y-realRectPoint[mm].y)+
					(realRectPoint[mm+1].x-realRectPoint[mm].x)
					*(realRectPoint[mm+1].x-realRectPoint[mm].x)));

				//printf("块%i,距离%f\n",mm,distRealRect[mm]);
			}

			findflag=true;
			for(int aa=0;aa<LINE_SQUARE_NUM-1;aa++)
			{
				//printf("块高度%d\n",realRect[0].bottom-realRect[0].top);
				if((distRealRect[aa])>1.4*(realRect[0].bottom-realRect[0].top))
				{
					findflag=false;
					break;
				}
			}
				
			break;
		}
	}
	
	if(findflag)
	{
		//查询九宫格标准色位置
		bool findJiu=false;
		for(int bb=0;bb<front_nSquare;bb++)
		{
			bool noJiu=false;
			for(int cc=0;cc<LINE_SQUARE_NUM;cc++)
			{
				if(bb==pSquareIndex[cc])
				{
					noJiu=true;
					break;
				}
			}
			if(noJiu)
				continue;

			stdRect[4]=SquarePos[bb].square_rect;
			//生成其他八个点的 位置
			SDPOINT neiboPoint[STD_SQUARE_NUM];
			int height=SquarePos[bb].square_rect.bottom-SquarePos[bb].square_rect.top;
			int width=SquarePos[bb].square_rect.right-SquarePos[bb].square_rect.left;
				
			int findJiuNum=0;
			DECTRECT bigRect;
			bigRect.left=pMidPoint[bb].x-1.5*width;
			bigRect.top=pMidPoint[bb].y-1.5*height;
			bigRect.right=pMidPoint[bb].x+1.5*width;
			bigRect.bottom=pMidPoint[bb].y+1.5*height;

			for(int ee=0;ee<front_nSquare;ee++)
			{
				bool noJiu=false;
				for(int cc=0;cc<11;cc++)
				{
					if(ee==pSquareIndex[cc])
					{
						noJiu=true;
						break;
					}
				}
				if(noJiu)
					continue;

				if(JudgeDotInRect(bigRect,pMidPoint[ee]))
				{
					//inRect=true;
					int rectWidth=SquarePos[ee].square_rect.right-SquarePos[ee].square_rect.left;
					int rectHeight=SquarePos[ee].square_rect.bottom-SquarePos[ee].square_rect.top;
					if(fabs(float(rectWidth-width))<5&&fabs(float(rectHeight-height))<5)
					{
						stdRect[findJiuNum]=SquarePos[ee].square_rect;
						findJiuNum++;
					}
				}

				if(findJiuNum==STD_SQUARE_NUM)
					break;
			}

			if(findJiuNum==STD_SQUARE_NUM)
			{
				findJiu=true;
				break;
			}
		}

		if(findJiu)
		{
			detectFlag=true;
			sortRectXY(stdRect, 9, 3);
		}
	}
	if(pMidPoint)
		delete pMidPoint;
	if(pSquareIndex)
		delete pSquareIndex;

	for(int i=0;i<linenum;i++)
	{
		if(lines[i])
			delete lines[i];
	}
	if(lines)
		delete lines;

	for(int i=0; i<LINE_SQUARE_NUM; i++)
	{
		pRealRect[i].left = realRect[i].left * scale_rate;
		pRealRect[i].right = realRect[i].right * scale_rate;
		pRealRect[i].top = realRect[i].top * scale_rate;
		pRealRect[i].bottom = realRect[i].bottom * scale_rate;
	}

	for(int i=0; i<STD_SQUARE_NUM; i++)
	{
		pStdRect[i].left = stdRect[i].left * scale_rate;
		pStdRect[i].right = stdRect[i].right * scale_rate;
		pStdRect[i].top = stdRect[i].top * scale_rate;
		pStdRect[i].bottom = stdRect[i].bottom * scale_rate;
	}
	
	return detectFlag;
}


void CalMeanBGR(unsigned char *color_image, int width, int height, DECTRECT *sample_rect, unsigned char &b, unsigned char &g, unsigned char &r)
{
	int left = sample_rect->left;
	int right = sample_rect->right;
	int top = sample_rect->top;
	int bottom = sample_rect->bottom;

	float mean_r = 0;
	float mean_g = 0;
	float mean_b = 0;
	int count_num = 0;

	for(int i=top; i<=bottom; i++)
	{
		for(int j=left; j<=right; j++)
		{
			int bgr_id = (i*width + j)*3;
			mean_r += color_image[bgr_id + 2];
			mean_g += color_image[bgr_id + 1];
			mean_b += color_image[bgr_id + 0];
			count_num++;

		}
	}
	r = int(mean_r / count_num);
	g = int(mean_g / count_num);
	b = int(mean_b / count_num);
}


bool CUHYRecogCls::BrightDetect(unsigned char* imageData,int wd, int ht,unsigned char lowValue=100,unsigned char highValue=200)
{
	float allBright=0;
	for(int i=0;i<ht;i++)
		for(int j=0;j<wd;j++)
		{
			allBright+=imageData[i*wd+j];
		}

	float averageBright=allBright/(wd*ht);

	if(averageBright<lowValue||averageBright>highValue)
		return false;
	else
		return true;
}



bool CUHYRecogCls::SquareDetectRecog(unsigned char* BGRData, int src_wd, int src_ht, RecogResult &pRealRes)
{

	bool brecog = false;

	DECTRECT realRect[11];
	DECTRECT stdRect[9];
	DECTRECT smallRealRect[11];
	DECTRECT smallStdRect[9];
	unsigned char *gray_data = new unsigned char[src_wd * src_ht];
	for(int i=0; i<src_ht; i++)
	{
		for(int j=0; j<src_wd; j++)
		{
			int gray_id = i*src_wd + j;
			int bgr_id = gray_id * 3;
			gray_data[gray_id] = (unsigned char)((int(7471) * BGRData[bgr_id] + int(38470) *  BGRData[bgr_id + 1] + int(19595) *  BGRData[bgr_id + 2]) >> 16);
		}
	}
	//进行检测
	brecog = SquareDetect(gray_data, src_wd, src_ht, pRealRes.realRect, pRealRes.stdRect);
	delete []gray_data;
	gray_data = NULL;

	if(!brecog)
	{
		return brecog; //如果检测失败，则返回
	}
	//计算11块的均值
	unsigned char b, g, r, mean_r, mean_g, mean_b;
	for(int ii = 0;ii < 11; ++ii)
	{
		realRect[ii] = pRealRes.realRect[ii];
		smallRealRect[ii]=GetSubRect(realRect[ii]);
	}

	float mean_std_bgr_inv[9];
	for(int jj=0;jj<9;jj++)
	{
		stdRect[jj] = pRealRes.stdRect[jj];
		smallStdRect[jj]=GetSubRect(stdRect[jj]);
		//记录9个标准块的平均颜色值
		CalMeanBGR(BGRData, src_wd, src_ht, smallStdRect + jj, mean_b, mean_g, mean_r);
		mean_std_bgr_inv[jj] = 1.0f / (mean_b + mean_g + mean_r);
	}

	///////////////////////////////     识别白细胞    ///////////////////////////////////////
	DECTRECT *sample_rect = smallRealRect + 0;
	pRealRes.baixibao_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 5, mean_std_bgr_inv, BaiXiBaoModel);

	///////////////////////////////     识别亚硝酸盐    ///////////////////////////////////////
	sample_rect = smallRealRect + 1;
	pRealRes.yaxiaosuanyan_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 3, mean_std_bgr_inv, YaXiaoSuanYanModel);

	///////////////////////////////     识别尿胆原    ///////////////////////////////////////
	sample_rect = smallRealRect + 2;
	pRealRes.niaodanyuan_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 5, mean_std_bgr_inv, NiaoDanYuanModel);

	///////////////////////////////     识别蛋白质   ///////////////////////////////////////
	sample_rect = smallRealRect + 3;
	pRealRes.danbaizhi_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 6, mean_std_bgr_inv, DanBaiZhiModel);

	///////////////////////////////     识别酸碱度   ///////////////////////////////////////
	sample_rect = smallRealRect + 4;
	pRealRes.suanjiandu_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 8, mean_std_bgr_inv, SuanJianDuModel);

	///////////////////////////////     识别潜血   ///////////////////////////////////////
	sample_rect = smallRealRect + 5;
	pRealRes.qianxue_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 5, mean_std_bgr_inv, QianXueModel);

	///////////////////////////////     识别比重   ///////////////////////////////////////
	sample_rect = smallRealRect + 6;
	pRealRes.bizhong_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 7, mean_std_bgr_inv, BiZhongModel);

	///////////////////////////////     识别酮体   ///////////////////////////////////////
	sample_rect = smallRealRect + 7;
	pRealRes.tongti_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 5, mean_std_bgr_inv, TongTiModel);

	///////////////////////////////     识别胆红素   ///////////////////////////////////////
	sample_rect = smallRealRect + 8;
	pRealRes.danhongsu_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 4, mean_std_bgr_inv, DanHongSuModel);

	///////////////////////////////     识别葡萄糖   ///////////////////////////////////////
	sample_rect = smallRealRect + 9;
	pRealRes.putaotang_idx = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 6, mean_std_bgr_inv, PuTaoTangModel);


	///////////////////////////////     识别抗坏血酸   ///////////////////////////////////////
	sample_rect = smallRealRect + 10;
	pRealRes.kanghuaixuesuan = RecogSingleRect(BGRData, src_wd, src_ht, sample_rect, 4, mean_std_bgr_inv, KangHuaiXueSuanModel);

	return brecog; 
}


/**
  * @brief								SVM predict value output
  * @param			[in]			ProVal - input vector1
  * @param			[in]			nClass - class number
  * @return							output label
  */
int MulClassfierJudge(float *ProVal, int nclassnum)
{
	int JudeIdx = 0;
	float MaxVal =ProVal[0];
	for( int i = 1; i < nclassnum; i++ )
	{
		float temp = ProVal[i];
		if(temp > MaxVal)
		{
			MaxVal = temp;
			JudeIdx = i;
		}
	}
	return JudeIdx;
}


int CUHYRecogCls::RecogSingleRect(unsigned char *src_data, int width, int height, DECTRECT *sample_rect, int class_num, float *mean_std_bgr_inv, const struct model *model_)
{
	
	unsigned char mean_r, mean_g, mean_b;
	CalMeanBGR(src_data, width, height, sample_rect ,mean_b, mean_g, mean_r);

	float *recog_conf_sum = new float [class_num];
	memset(recog_conf_sum, 0, sizeof(float)*class_num);

	float *recog_conf = new float [class_num];

	int left = sample_rect->left;
	int right = sample_rect->right;
	int top = sample_rect->top;
	int bottom = sample_rect->bottom;

	unsigned char u_r, u_g, u_b;
	float color_feature[33];
	for(int i=top; i<=bottom; i++)
	{
		for(int j=left; j<=right; j++)
		{
			int bgr_id = (i*width + j)*3;
			u_r = src_data[bgr_id + 2];
			u_g = src_data[bgr_id + 1];
			u_b = src_data[bgr_id + 0];
			color_feature[0] = ((float)u_r) / mean_r;
			color_feature[1] = ((float)u_g) / mean_g;
			color_feature[2] = ((float)u_b) / mean_b;
			color_feature[3] = ((float)u_r) * 0.003921568627451f;
			color_feature[4] = ((float)u_g) * 0.003921568627451f;
			color_feature[5] = ((float)u_b) * 0.003921568627451f;

			int count_pix = 6;
			for(int k=0; k<9; k++)
			{
				color_feature[count_pix] = (float)u_r * mean_std_bgr_inv[k];
				count_pix++;
				color_feature[count_pix] = (float)u_g * mean_std_bgr_inv[k];
				count_pix++;
				color_feature[count_pix] = (float)u_b * mean_std_bgr_inv[k];
				count_pix++;
			}
			predict_probability_new(model_, color_feature, recog_conf);

			for(int k=0; k<class_num; k++)
			{
				recog_conf_sum[k] += recog_conf[k];
			}

		}
	}

	int recog_idx = MulClassfierJudge(recog_conf_sum, class_num);

	delete []recog_conf_sum;
	recog_conf_sum = NULL;
	delete []recog_conf;
	recog_conf = NULL;

	return recog_idx;
}

void CUHYRecogCls::DetectRelease()
{
	if(SquarePos)
	{
		delete SquarePos;
		SquarePos=NULL;
	}

	if(Front_FastDetectCls)
	{
		delete Front_FastDetectCls;
		Front_FastDetectCls=NULL;
	}

	free_and_destroy_model(&BaiXiBaoModel);
	free_and_destroy_model(&YaXiaoSuanYanModel);
	free_and_destroy_model(&NiaoDanYuanModel);
	free_and_destroy_model(&DanBaiZhiModel);
	free_and_destroy_model(&SuanJianDuModel);
	free_and_destroy_model(&QianXueModel);
	free_and_destroy_model(&BiZhongModel);
	free_and_destroy_model(&TongTiModel);
	free_and_destroy_model(&DanHongSuModel);
	free_and_destroy_model(&PuTaoTangModel);
	free_and_destroy_model(&KangHuaiXueSuanModel);
	
}



